package com.javasm.aop;

import com.javasm.annotation.Permission;
import com.javasm.domain.AuthenConstant;
import com.javasm.domain.LoginUser;
import com.javasm.exception.AuthenticationException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;

/**
 * @Author：MoDebing
 * @Version：1.0
 * @Date：2022-09-02-00:18
 * @Description:
 */
@Aspect
@Component
@Slf4j
public class AuthenticationAop {

    // 通过注解拦截
    //@Pointcut("@annotation(com.javasm.annotation.Permission)")
    public void method(){}

    //@Before("method()")
    public void verify(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        Permission annotation = methodSignature.getMethod().getAnnotation(Permission.class);
        if (Objects.isNull(annotation)){
            throw new RuntimeException("no authentication");
        }
        //拿到自定义权限上的注解
        AuthenConstant[] authenticationMethod = annotation.authentication();
        // 去和框架上的注解去比对，如果正确，则放行，否则报错提示没有权限
        Authentication authentication1 = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication1.getPrincipal();
        String userName = loginUser.getUser().getUserName();
        Collection<? extends GrantedAuthority> authorities = authentication1.getAuthorities();
        String className =method.getDeclaringClass().getName();
        String methodName = method.getName();
        for (GrantedAuthority userAuthority : authorities) {
            String userAuthorityAuthority = userAuthority.getAuthority();
            for (AuthenConstant authenConstant : authenticationMethod) {
                if (authenConstant.getAuthentication().equals(userAuthorityAuthority)){
                    log.info("当前登录用户为：{}",userName);
                    log.info("当前用户使用的权限:{}", Arrays.toString(authenticationMethod));
                    log.info("当前用户访问的方法名为:{}",className+"."+methodName);
                    return;
                }
            }
        }
        throw new AuthenticationException("用户没有权限！");
    }
}
